import SocketServer
import socket
import re
import random
class ProxyServer(SocketServer.ThreadingTCPServer):
	""" the server class inherited from Threading TCPServer"""
	def __init__(self, server_address, RequestHandlerClass):
		""" Set up"""
		SocketServer.ThreadingTCPServer.__init__(self,server_address,RequestHandlerClass)
		#SocketServer.ThreadingTCPServer.allow_reuse_address = True
		#self.users: save user's ip and its wfile
		self.users = {}
		self.monitors = {}
		self.videoMonitor = None



class RequestHandler(SocketServer.StreamRequestHandler):
	"""handler """
	IPADDRESS = re.compile('^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$')
	MONITOR_NAME=re.compile('^monitor.*$')
	def handle(self):
		self.userIP = False
		self.monitorName = False
		message = self._readline()
		if self.IPADDRESS.match(message):
			self.userIP = message
			self.server.users[self.userIP]=self.wfile
			print self.userIP
			self._handle_node()
		
		
		if message == 'subscribe':
			self._handle_subscribe()
			#save the wfile as self.server.monitors['video'] = self.wfile
			
			#get the ip address of node
			
			#send message to node to start video monitor process

		
		#if message == 'video':
		#	self._handle_accept_video()
			#it is the video file from node
			#_handle_video
		else:
			print "%s does not match"%message
			# it is a monitor, save its wfile in the dictionary
			#firstly, check whether there are montor already existing
			newMonitorName='monitor'
			if self.server.monitors:
				while True:
					newMonitorName = newMonitorName+str(random.randint(1,5))
					if not self.server.monitors.get(newMonitorName):
						break	
			print "new name:",newMonitorName
			self.server.monitors[newMonitorName]=self.wfile
			self.server.monitors[newMonitorName].write("it is test message\n")	
			self.monitorName = newMonitorName
			self._handle_monitor()
			
			
			
	def _handle_subscribe(self):
		#save its writefile to self.server.videoMonitor
		if self.server.videoMonitor:
			self.wfile.write("there is already a monitor exists\n")
			return
		self.server.videoMonitor = self.wfile
		message = self._readline()#get the node information the monitor want to subscribe
		self.server.users[message].write("\x08\r\n")
		s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
		s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
		s.bind(2628)
		s.listen(1)
		connfd,client_addr = s.accpet()
		while True:
			data = connfd.recv(1024)
			if not data:
				break
			while len(data)> 0:
				sent = cs.send(data)
				data = data[sent:]
		
		
	
	def _handle_accept_video(self):
		#send a new message with title 0x08
		
		newMessage = True
		while newMessage:
			try:
				newMessage = self._readline()
				if newMessage == 'exit':
					break
			except socket.error, e:
				newMessage = False
	
	def _handle_video(self):
		pass
		#while True
		#	receive data
		#	redirect data to video monitor: self.server.monitors['video'].write(data)
		
	def _handle_node(self):
		newMessage = True
		while newMessage:
			try:
				newMessage = self._readline()
				self._print(newMessage)
				print self.server.users
			except socket.error, e:
				newMessage = False
				
	def _handle_monitor(self):
		newMessage = True
		while newMessage:
			try:
				newMessage = self._readline()
			except socket.error, e:
				newMessage = False
	
	
	def sendToMonitor(self,s):
			for monitor in self.server.monitors:
				self.server.monitors[monitor].write(self._ensureNewline(s))
			
		
	
	def finish(self):
		""" automatically called when handle() is done."""
		print "at finish"
		if self.monitorName:
			if self.server.monitors.get(self.monitorName):
				del(self.server.monitors[self.monitorName])
				print self.server.monitors
				print "monitor %s exits"%self.monitorName
		
		if self.userIP:
			""" we have already got the IP of this node"""
			if self.server.users.get(self.userIP):
				del(self.server.users[self.userIP])
				print self.server.users
				print "server \"", self.userIP,"\" has left!"
							
		self.request.shutdown(2)
		self.request.close()
				
				
				
	def _print(self,s):
			print self._ensureNewline(s)
			#if the monitor has already connected
			if self.server.monitors:
				self.sendToMonitor(s)
				
	def _readline(self):
		"""Reads a line, removing any whitespace. """
		return self.rfile.readline().strip()
	
	def _writeline(self,s):
		self.wfile.write(self._ensureNewline(s))
		
	def _ensureNewline(self, s):
		if s and s[-1] != '\n':
			print "change s"
			s += '\r\n'
		return s
	
	
	
	
	
if __name__ == '__main__':
	import sys
	myServer = ProxyServer(('localhost',2627), RequestHandler)
	myServer.socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
	myServer.serve_forever()